{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "在 Python 中，函数是一等对象。编程语言研究人员把“一等对象”定义为满足以下条件的程序实体：\n",
    "* 在运行时创建；\n",
    "* 能赋值给变量或数据结构中的元素；\n",
    "* 能作为参数传给函数；\n",
    "* 能作为函数的返回结果。"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "函数由两部分组成：**代码对象** 和 **函数对象**。\n",
    "1. 代码对象（code object）：代码对象是函数中的核心部分，它持有函数的字节码（bytecode）和指令元数据。字节码是一系列由解释器执行的低级指令，它们定义了函数的操作和行为。指令元数据提供关于字节码的附加信息，例如变量名称、行号映射等。代码对象负责执行函数的字节码，并管理函数执行过程中所需的指令和数据。\n",
    "2. 函数对象（function object）：函数对象是函数的表示，它为上下文提供了调用函数的实例，并管理函数的状态数据。函数对象可以被调用，就像调用普通的函数一样，通过传递参数并执行函数的代码。函数对象还可以跟踪函数的状态，例如局部变量、闭包、默认参数等。它还可以存储函数的属性，例如函数的名称、模块、文档字符串等。\n",
    "\n",
    "综合起来，函数的代码对象负责执行函数代码的字节码，并提供指令元数据的附加信息。函数对象则作为函数的实例，用于管理函数的上下文和状态数据。这两个部分共同组成了函数的完整实现和功能。"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 代码对象（Code Object）：\n",
    "* 代码对象是Python中表示可执行代码的一种数据结构。\n",
    "* 它包含函数的字节码指令、常量、变量名称、异常处理信息等。\n",
    "* 代码对象是不可变的，一旦创建就不能修改。\n",
    "* 代码对象由解释器在函数定义时动态创建。\n",
    "* 代码对象可以通过__code__属性来访问。\n",
    "\n",
    "### 字节码（Bytecode）：\n",
    "\n",
    "* 字节码是一种中间形式的代码表示，它由解释器执行。\n",
    "* 函数的源代码在运行之前会被编译为字节码。\n",
    "* 字节码是一系列低级指令，每个指令都对应一个特定的操作，例如加载变量、执行函数调用、进行算术计算等。\n",
    "* 字节码的执行由解释器完成。"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "ExecuteTime": {
     "end_time": "2024-02-25T01:36:24.617710800Z",
     "start_time": "2024-02-25T01:36:24.609097300Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<code object test_fun at 0x000002783BE74D50, file \"C:\\Users\\touchx\\AppData\\Local\\Temp\\ipykernel_10284\\2910431878.py\", line 1>\n",
      "('x', 'y')\n",
      "(None, 100)\n"
     ]
    }
   ],
   "source": [
    "def test_fun(x,y=10):\n",
    "    x += 100\n",
    "    print(x,y)\n",
    "\n",
    "print(test_fun.__code__)\n",
    "print(test_fun.__code__.co_varnames)\n",
    "print(test_fun.__code__.co_consts)"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 函数对象（Function Object）：\n",
    "\n",
    "* 函数对象是表示函数的实例，它是可调用的。\n",
    "* 函数对象是一种可变对象，它可以存储和管理函数的状态数据。\n",
    "* 函数对象提供了对函数代码的执行环境的访问，并允许函数被调用和执行。\n",
    "* 函数对象还可以存储函数的属性，例如名称、模块、文档字符串等。\n",
    "\n",
    "### 函数调用：\n",
    "\n",
    "* 当调用函数时，函数对象会创建一个新的执行上下文（execution context）。\n",
    "* 执行上下文包含函数的局部变量、参数、返回值等。\n",
    "* 在执行上下文中，函数的代码被解释器逐条执行，指令按照字节码的顺序执行。\n",
    "* 函数执行过程中可以访问和修改局部变量，并且可以调用其他函数。\n",
    "\n",
    "### 函数的状态：\n",
    "\n",
    "* 函数对象可以存储和管理函数的状态数据。\n",
    "* 在函数执行期间，可以在函数对象中创建和更新状态数据。\n",
    "* 这些状态数据可以是函数的局部变量、闭包中的变量、默认参数值等。\n",
    "* 函数的状态可以在函数调用之间保持，并且可以影响函数的行为和计算结果。\n",
    "\n",
    "### 函数闭包（Function Closure）：\n",
    "* 闭包是函数对象和其相关环境的组合。\n",
    "* 当函数定义在另一个函数内部时，内部函数可以访问外部函数的变量和作用域。\n",
    "* 当内部函数被返回并在外部函数之外调用时，它依然可以访问和操作外部函数的变量。\n",
    "* 这种行为是因为闭包捕获了外部函数的状态，并将其封装在内部函数中。\n",
    "* 闭包可以用于实现函数工厂、保持状态、实现私有变量等。\n",
    "\n",
    "### 默认参数（Default Parameters）：\n",
    "* 默认参数是函数定义时指定的参数值，当函数被调用时，如果没有提供相应的参数，则使用默认值。\n",
    "* 默认参数允许函数在不同的调用中接受不同数量的参数，或者在某些参数未提供时使用预定义的值。\n",
    "* 默认参数的值在函数定义时被计算，并且只计算一次，之后在每次函数调用时都使用相同的值。\n",
    "\n",
    "### 变长参数（Variable-length Parameters）：\n",
    "* 变长参数允许函数接受可变数量的参数。\n",
    "* 在Python中，有两种变长参数的方式：*args和**kwargs。\n",
    "* *args表示接受任意数量的位置参数，它会将传递的参数打包成一个元组。\n",
    "* **kwargs表示接受任意数量的关键字参数，它会将传递的参数打包成一个字典。"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1234,)\n",
      "101 1234\n",
      "{'abc': 'hello, world'}\n"
     ]
    }
   ],
   "source": [
    "print(test_fun.__defaults__)  # 参数默认值\n",
    "test_fun.__defaults__=(1234,)  # 修改默认值\n",
    "test_fun(1)\n",
    "\n",
    "test_fun.abc = \"hello, world\" # 为函数实例添加属性\n",
    "print(test_fun.__dict__)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-02-25T01:39:19.506214200Z",
     "start_time": "2024-02-25T01:39:19.495878600Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "\n",
    "\n",
    "### 递归（Recursion）：\n",
    "* 递归是指函数调用自身的过程。\n",
    "* 递归可以用于解决可以被分解为相同问题的子问题的情况。\n",
    "* 递归函数包括一个或多个基本情况（base case），用于终止递归的条件，以及一个或多个递归情况（recursive case），用于将问题分解为较小的子问题。\n",
    "\n",
    "### 函数装饰器（Function Decorators）：\n",
    "* 函数装饰器是用于修改其他函数行为的函数。\n",
    "* 装饰器可以在不修改被装饰函数源代码的情况下，通过添加额外的功能来改变函数的行为。\n",
    "* 装饰器通常使用@符号将其应用于被装饰的函数。\n",
    "\n",
    "### 高阶函数（Higher-Order Functions）\n",
    "* 高阶函数是指能够接受函数作为参数或返回函数作为结果的函数。\n",
    "* 在Python中，函数是一等公民，因此可以像其他数据类型一样作为参数传递和返回值使用。\n",
    "* 高阶函数可以用于实现回调机制、函数组合、延迟执行等功能。\n",
    "\n",
    "### 生成器函数（Generator Functions）：\n",
    "* 生成器函数是一种特殊的函数，它使用yield关键字来定义。\n",
    "* 生成器函数的执行会生成一个迭代器（iterator），通过迭代器可以按需生成值，而不是一次性生成所有值。\n",
    "* 生成器函数的特点是可以暂停和恢复执行，从而有效地处理大量数据或无限序列。\n",
    "\n",
    "### 匿名函数（Lambda Functions）：\n",
    "* 匿名函数是一种没有名称的函数，它通常用于简单的函数表达式。\n",
    "* 在Python中，可以使用lambda关键字来创建匿名函数。\n",
    "* 匿名函数常用于作为高阶函数的参数，或者在需要简短函数定义的地方。\n",
    "\n",
    "### 作用域和命名空间（Scope and Namespace）：\n",
    "* 作用域是指在程序中访问变量的有效范围。\n",
    "* 在Python中，函数和类定义都会引入新的作用域。\n",
    "* 每个作用域都有一个对应的命名空间，用于存储变量和函数名字与对象之间的映射关系。\n",
    "* 在函数中，局部变量在函数的命名空间中有效，而全局变量在全局命名空间中有效。\n",
    "\n",
    "### 内置函数（Built-in Functions）：\n",
    "* Python提供了许多内置函数，这些函数是Python解释器提供的预定义函数，可以直接使用。\n",
    "* 内置函数包括print()、len()、range()、sum()等，它们提供了常见的操作和功能。\n",
    "* 通过使用内置函数，可以方便地执行各种常见的任务，而无需重新实现这些功能。\n",
    "\n",
    "### 递归函数的优化：\n",
    "* 递归函数在处理大规模问题时可能会导致内存溢出或性能问题。\n",
    "* 为了优化递归函数，可以使用尾递归（tail recursion）或迭代的方式重写递归算法。\n",
    "* 尾递归是指递归函数的最后一个操作是递归调用本身，且递归调用的返回值直接返回而不需要其他计算。\n",
    "* 一些编程语言支持尾递归优化，将尾递归函数转换为迭代形式，从而避免了递归调用的堆栈累积。\n",
    "\n",
    "### 函数式编程（Functional Programming）：\n",
    "* 函数式编程是一种编程范式，它将计算视为函数求值的过程。\n",
    "* 函数式编程强调使用纯函数（pure function）进行计算，即没有副作用的函数，相同输入产生相同输出。\n",
    "* 函数式编程推崇不可变数据（immutable data）和避免共享状态，通过组合和高阶函数实现复杂的计算逻辑。\n",
    "\n",
    "### 闭包和垃圾回收（Closure and Garbage Collection）：\n",
    "* 在使用闭包时，需要注意内部函数引用的外部变量，因为闭包会导致变量的引用计数不为零，从而可能影响垃圾回收的行为。\n",
    "* 在某些情况下，如果闭包中的函数长时间存在，可能会导致内存泄漏或资源无法释放。\n",
    "* 可以考虑手动解除对闭包的引用，或者使用weakref模块中的弱引用来避免循环引用问题。\n",
    "\n",
    "### 装饰器的应用：\n",
    "* 装饰器是一种常见的Python编程技巧，用于修改、扩展或包装函数的行为。\n",
    "* 装饰器可以用于添加日志、计时、缓存、权限检查等功能，而不需要修改被装饰函数的源代码。\n",
    "* Python提供了functools模块，其中包括一些有用的装饰器，例如lru_cache用于缓存函数调用结果。\n",
    "\n",
    "### 并发和并行编程：\n",
    "* 并发是指程序设计的一种特性，多个任务可以同时执行，但不一定是并行执行（同时使用多个处理器）。\n",
    "* 并行是指多个任务同时在多个处理器上执行。\n",
    "* Python提供了多线程（threading）和多进程（multiprocessing）模块，用于实现并发和并行编程。\n",
    "* 在使用多线程和多进程时，需要注意线程安全和进程间通信等问题。\n",
    "\n",
    "### 异常处理（Exception Handling）：\n",
    "* 异常是在程序执行过程中发生的错误或异常情况。\n",
    "* 在函数中，可以使用try-except语句来捕获和处理异常。\n",
    "* try块用于包含可能引发异常的代码，而except块用于指定异常类型并定义处理异常的逻辑。\n",
    "* 异常处理使得程序能够优雅地处理错误情况，并提供了错误恢复和异常信息报告的机制。\n",
    "\n",
    "### 生成器表达式（Generator Expressions）：\n",
    "* 生成器表达式是一种类似于列表推导的语法，用于生成一个生成器对象。\n",
    "* 生成器表达式使用圆括号而不是方括号，可以按需生成值，而不是一次性生成所有值。\n",
    "* 生成器表达式在处理大量数据时非常高效，因为它们可以节省内存并提供惰性计算的能力。\n",
    "\n",
    "### 函数注解（Function Annotations）：\n",
    "* 函数注解是一种在函数定义中添加元数据的方式，用于指定参数和返回值的类型或其他相关信息。\n",
    "* 函数注解使用冒号后面的表达式来指定类型，可以用于静态类型检查、文档生成等目的。\n",
    "* 函数注解不会影响函数的实际行为，只是提供了一种附加的说明和约定。\n",
    "\n",
    "### 生成器迭代器协议（Generator Iterator Protocol）：\n",
    "* 生成器迭代器协议是指生成器对象实现的接口，使其可以被迭代器函数和其他迭代工具使用。\n",
    "* 生成器对象是迭代器的一种特殊形式，它通过yield语句按需生成值，并在每次迭代时暂停和恢复执行。\n",
    "* 生成器迭代器协议定义了__iter__()和__next__()等特殊方法，允许生成器对象被for循环等迭代工具使用。\n",
    "\n",
    "### 函数式编程库：\n",
    "* 在Python中，有一些流行的函数式编程库，如functools、itertools和operator等。\n",
    "* functools库提供了一些高阶函数、装饰器和其他实用工具，如partial()、reduce()和compose()等。\n",
    "* itertools库提供了一组用于迭代和组合的工具函数，如count()、cycle()和permutations()等。\n",
    "* operator库提供了一些用于执行常见操作的函数，如算术运算、比较和逻辑运算等。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
